package com.ui.controls
{
	import com.ui.containers.TitleWindow;
	import com.ui.core.Align;
	import com.ui.data.AlertData;
	import com.ui.data.ButtonData;
	import com.ui.layout.GLayout;
	import com.ui.manager.UIManager;

	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.utils.clearInterval;
	import flash.utils.setTimeout;

	/**
	 * Game Alert
	 * 
	 * @author Cafe
	 * @version 20100727
	 */
	public class Alert extends TitleWindow
	{
		public static const NONE:uint = 0x0000;
		public static const OK:uint = 0x0004;
		public static const CANCEL:uint = 0x0008;
		public static const YES:uint = 0x0001;
		public static const NO:uint = 0x0002;
		protected var _alertData:AlertData;
		protected var _label:Label;
		protected var _textInput:TextInput;
		protected var _buttons:Array;
		protected var _timeout:int = 0;
		protected var _detail:uint;

		private function initView():void
		{
			// 用于部分允许拖动的alert
			if (_data.titleBarData.labelData.text == "") _titleBar.hide();
			addLabels();
			addTextInput();
			addButtons();
			autoSize();
		}

		private function addLabels():void
		{
			_label = new Label( _alertData.labelData );
			_contentPanel.add( _label );
		}

		private function addTextInput():void
		{
			if (_alertData.textInputData)
			{
				_alertData.textInputData.align = Align.HCENTER;
				_textInput = new TextInput( _alertData.textInputData );
				_contentPanel.add( _textInput );
			}
		}

		private function addButtons():void
		{
			_buttons = new Array();
			if (_alertData.flag == NONE) return;
			var data:ButtonData;
			var button:Button;
			if (_alertData.flag & OK)
			{
				data = _alertData.buttonData.clone();
				data.labelData.text = _alertData.okLabel;
				button = new Button( data );
				button.source = OK;
				_buttons.push( button );
			}
			if (_alertData.flag & YES)
			{
				data = _alertData.buttonData.clone();
				data.labelData.text = _alertData.yesLabel;
				button = new Button( data );
				button.source = YES;
				_buttons.push( button );
			}
			if (_alertData.flag & NO)
			{
				data = _alertData.buttonData.clone();
				data.labelData.text = _alertData.noLabel;
				button = new Button( data );
				button.source = NO;
				_buttons.push( button );
			}
			if (_alertData.flag & CANCEL)
			{
				data = _alertData.buttonData.clone();
				data.labelData.text = _alertData.cancelLabel;
				button = new Button( data );
				button.source = CANCEL;
				_buttons.push( button );
			}
			for each (button in _buttons)
			{
				button.addEventListener( MouseEvent.CLICK, clickHandler );
				_contentPanel.add( button );
			}
		}

		/**
		 * 点击按钮的时候发出close事件，同时设置detail
		 */
		protected function clickHandler( event:MouseEvent ):void
		{
			var source:uint = Button( event.currentTarget ).source;
			if (source == YES)
			{
				_detail = YES;
			}
			else if (source == NO)
			{
				_detail = NO;
			}
			else if (source == OK)
			{
				_detail = OK;
			}
			else if (source == CANCEL)
			{
				_detail = CANCEL;
			}
			else
			{
				_detail = NONE;
			}
			hide();
			dispatchEvent( new Event( Event.CLOSE ) );
		}

		/**
		 * 根据所拥有的按钮进行布局
		 */
		protected function autoSize( needLayout:Boolean = true ):void
		{
			var numButtons:int = Math.max( _buttons.length, 1 );
			var labelWidth:int = _label.width + _data.panelData.padding * 2;
			var labelHeight:int = _label.height + (_alertData.flag == Alert.NONE ? 0 : _alertData.vgap);
			var textInputWidth:int = (_textInput ? _textInput.width + _data.panelData.padding * 2 : 0);
			var textInputHeight:int = (_textInput ? _textInput.height + _alertData.vgap : 25);
			var buttonWidth:int = (_alertData.flag == Alert.NONE ? 0 : numButtons * _alertData.buttonData.width + (numButtons - 1) * _alertData.hgap + _data.panelData.padding * 2);
			var buttonHeight:int = (_alertData.flag == Alert.NONE ? 0 : _alertData.buttonData.height);
			_width = Math.max( _data.minWidth, labelWidth, textInputWidth, buttonWidth ) + 20;
			_height = Math.max( _data.minHeight, labelHeight + textInputHeight + buttonHeight + _data.panelData.padding * 2 ) + _titleBar.height;
			_label.x = int( (_width - labelWidth) * 0.5 );
			_label.y = int( (_height - labelHeight - textInputHeight - _titleBar.height - buttonHeight - _data.panelData.padding * 2) * 0.5 );
			if (_titleBar.parent)
			{
				_titleBar.y += _titleBar.height;
				_label.y += _titleBar.height;
			}

			if (_textInput)
			{
				_textInput.width = _width * .6;
				_textInput.x = int( (_width - _textInput.width) * 0.5 );
				_textInput.y = _label.height + _alertData.vgap;
				// GLayout.layout(_textInput);
			}
			if (_alertData.flag != Alert.NONE)
			{
				var newY:int = _height - buttonHeight - _data.panelData.padding * 2 - _titleBar.height - 5;
				var newWidth:int = _buttons.length * (_alertData.buttonData.width + _alertData.hgap) - _alertData.hgap;
				var newX:int = Math.floor( (_width - newWidth - _data.panelData.padding * 2) * 0.5 );
				for each (var button:Button in _buttons)
				{
					button.moveTo( newX, newY );
					newX += button.width + _alertData.hgap;
				}
			}
			if (needLayout)
				super.layout();
		}

		public function setButtonText( text:String, index:uint ):void
		{
			Button( _buttons[index] ).text = text;
			
		}

		protected function initEvents():void
		{
		}

		private function keyUPHandler( event:KeyboardEvent ):void
		{
			if (event.keyCode != 13) return;

			if (_alertData.flag & OK)
			{
				_detail = OK;
			}
			else if (_alertData.flag & YES)
			{
				_detail = YES;
			}
			else if (_alertData.flag & NO)
			{
				_detail = NO;
			}
			else if (_alertData.flag & OK)
			{
				_detail = OK;
			}
			else if (_alertData.flag & CANCEL)
			{
				_detail = CANCEL;
			}
			else if (_alertData.flag == NONE)
			{
				_detail = NONE;
			}

			hide();
			dispatchEvent( new Event( Event.CLOSE ) );
		}

		public function set showShadow( value:Boolean ):void
		{
			_alertData.showShadow = value;
		}

		override protected function onShow():void
		{
			if (_alertData.showShadow)
			{
				super.onShow();
			}
			else
			{
				if (_data.allowDrag)
				{
					_titleBar.addEventListener( MouseEvent.MOUSE_DOWN, super.titleBar_mouseDownHandler );
				}
			}
			if (_timeout != 0)
			{
				clearInterval( _timeout );
				_timeout = 0;
			}
			if (_textInput != null)
			{
				_textInput.setFocus();
				_textInput.selectAll();
			}
			_titleBar.y += 4;
			_titleBar.baseData.width = width;
			_titleBar.resetBG();
			GLayout.layout( this );
			UIManager.root.stage.addEventListener( KeyboardEvent.KEY_UP, keyUPHandler );
		}

		public function Alert( data:AlertData )
		{
			_alertData = data;
			_alertData.modal = data.showShadow;
			super( data );
			initView();
			initEvents();
		}

		override public function hide():void
		{
			UIManager.root.stage.removeEventListener( KeyboardEvent.KEY_UP, keyUPHandler );
			if (_data.modal && _modalSkin.parent)
			{
				_modalSkin.parent.removeChild( _modalSkin );
			}
			super.hide();
			if (_timeout != 0)
			{
				clearInterval( _timeout );
				_timeout = 0;
			}
		}

		public function set flag( flag:uint ):void
		{
			if (_alertData.flag == flag) return;
			_alertData.flag = flag;
			for each (var button:Button in _buttons)
			{
				button.hide();
			}
			addButtons();
			autoSize();
			GLayout.layout( this );
		}

		public function showWait( delay:int = 500 ):void
		{
			if (_timeout != 0)
			{
				clearInterval( _timeout );
				_timeout = 0;
			}
			_timeout = setTimeout( show, delay );
		}

		public function set label( value:String ):void
		{
			_label.text = value;
			autoSize();
		}

		public function hideWait( delay:int = 500 ):void
		{
			if (_timeout != 0)
			{
				clearInterval( _timeout );
				_timeout = 0;
			}
			_timeout = setTimeout( function():void
			{
				hide();
			}, 3000 );
		}

		public function set inputText( value:String ):void
		{
			if (_textInput != null)
			{
				_textInput.text = String( value );
			}
		}

		public function get textInput():TextInput
		{
			return _textInput;
		}

		public function get inputText():String
		{
			if (_textInput)
			{
				return _textInput.text;
			}
			return "";
		}

		public function get detail():uint
		{
			return _detail;
		}
	}
}
